import axios from 'axios'
import store from '@/store'
import router from '@/router'
import { Toast } from 'vant'

// *使用axios来创建axios的实例对象并配置
const instance = axios.create({
  baseURL: 'http://toutiao.itheima.net',
  timeout: 5000
})

// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    // 获取token，然后配置token
    const token = store.state.user.token.token
    // 判断token是否存在再去配置
    if (token) {
      config.headers.Authorization = 'Bearer ' + token
    }

    // console.log(config.headers.Authorization)
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    return response.data
  },
  async function (error) {
    console.log(error)
    // if (error.response.status === 401) {
    //   // 响应为401时跳转到login
    //   // js中不能使用this.$router,需要另外导入router
    //   // router.push('/login')
    //   // !活的写法
    //   router.push({
    //     path: '/login',
    //     query: {
    //       // 带回来的地址
    //       // 在vue组件中，通过this.$route.fullPath可以获取到当前路由地址
    //       // 在js中通过router.currentRoute获取到当前路由信息(router.currentRoute===this.$route)
    //       back: router.currentRoute.fullPath
    //     }
    //   })
    // }

    // todo 无感刷新==>一旦token过期，使用refresh_token找服务器获取到最新的token拿来使用
    if (error.response.status === 401) {
      // 开始无感刷新
      // 去vuex中获取refresh_Token
      const refreshToken = store.state.user.token.refresh_token
      console.log(refreshToken)
      if (refreshToken) {
        try {
          // 本地有refreshToken

          // 发请求，根据刷新token来获取新的用户token
          // !只能使用axios，不能使用instance(instance配置有请求拦截器，每次请求会带上有问题的token)
          const res = await axios({
            url: 'http://toutiao.itheima.net/v1_0/authorizations',
            method: 'PUT',
            headers: {
              Authorization: 'Bearer ' + refreshToken
            }
          })
          console.log(res)
          // 将获取到的新的token存储到本地+vuex中
          store.commit('user/setToken', {
            // token是新的获取到的token
            token: res.data.data.token,
            // refresh_Token是已经存储的之前的刷新token
            refresh_token: refreshToken
          })

          // 获取到新的token之后再去发请求，使用instance来发，因为配置了请求拦截器(会带上有效的新token)
          return instance(error.config)
        } catch {
          // refresh_token也过期了，去登录
          goLogin()
        }
      } else {
        // 没有refreshToken
        goLogin()
      }
    } else {
      // 非401的token错误
      // Promise.reject()返回失败的promise对象
      // Promise.resolve()返回成功的promise对象
      return Promise.reject(error)
    }
  }
)

// *对外导出axios的实例对象使用
export default instance

function goLogin() {
  // 把vuex和本地存储的token给清除掉==>注意：调用vuex中的mutations的removeToken方法，一定要区分是user模块下的mutations方法
  store.commit('user/removeToken')
  // 提示下
  Toast.fail('登录过期，请重新登录')
  // 跳转去登录页面
  router.push({
    path: '/login',
    query: {
      // 带回来的地址
      // 在vue组件中，通过this.$route.fullPath可以获取到当前路由地址
      // 在js中通过router.currentRoute获取到当前路由信息(router.currentRoute===this.$route)
      back: router.currentRoute.fullPath
    }
  })
}
